﻿using CoffeeShop.Models.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace CoffeeShop.Common
{
    public static class CmnFunc
    {
        public const string ADMIN_ROLE_VALUE = "Admin";
        public const string MANAGER_ROLE_VALUE = "Manager";
        public const string STAFF_ROLE_VALUE = "Staff";
        public const string CUSTOMER_ROLE_VALUE = "Customer";
        public const string PRODUCT_IMAGE_PATH = "~/Image/ProductImage/";
        public const string PRODUCT_IMAGE_PATH_SHOW = "/Image/ProductImage/";
        private static CFMSEntities _entities = new CFMSEntities();

        /// <summary>
        /// Parse from string to MD5
        /// </summary>
        /// <param name="md5Hash"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMd5Hash(MD5 md5Hash, string input)
        {

            // Convert the input string to a byte array and compute the hash. 
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes 
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data  
            // and format each one as a hexadecimal string. 
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string. 
            return sBuilder.ToString();
        }

        /// <summary>
        /// Convert user's password to MD5
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static string ConvertToMD5(string password)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                string hash = GetMd5Hash(md5Hash, password);

                return hash;
            }
        }

        /// <summary>
        /// Get RoleId based on RoleName
        /// </summary>
        /// <param name="roleName">roleName: RoleName</param>
        /// <returns>int: RoleId</returns>
        public static int GetRoleByRoleName(string roleName)
        {
            try
            {
                var selectRole = (from role in _entities.Roles
                                 where role.RoleName == roleName
                                 select role).FirstOrDefault();
                return selectRole.RoleId;
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.ToString());
                throw ex;
            }
        }

        private static IDictionary<string, object> ConvertObjectToJson(object data, int currentLevel, List<string> exceptAttr, params List<string>[] include)
        {
            var result = new Dictionary<string, object>();

            var attrs = data.GetType().GetProperties();
            int maxLevel = include.Length;
            foreach (var attr in attrs)
            {
                var value = attr.GetValue(data, null);

                if (value != null && value.ToString().StartsWith("System.Data.Entity"))       // attribute is an object
                {
                    if (currentLevel < maxLevel && include[currentLevel].IndexOf(attr.Name) != -1)
                    {
                        result.Add(attr.Name, ConvertObjectToJson(value, currentLevel + 1, exceptAttr, include));
                    }
                }

                else if (value != null && value.ToString().StartsWith("System.Collections"))    // attribute is a list
                {
                    if (currentLevel < maxLevel && include[currentLevel].IndexOf(attr.Name) != -1)
                    {
                        var list = new List<object>();
                        foreach (var i in (IEnumerable<object>)value)
                        {
                            list.Add(ConvertObjectToJson(i, currentLevel + 1, exceptAttr, include));
                        }
                        result.Add(attr.Name, list);
                    }
                }
                else
                {
                    if (exceptAttr.IndexOf(attr.Name) != -1) break;
                    result.Add(attr.Name, attr.GetValue(data, null));
                }
            }

            return result;
        }

        public static IDictionary<string, object> ConvertDynamicObjectWithFullAttr(object data, params List<string>[] include)
        {
            return ConvertObjectToJson(data, 0, new List<string>(), include);
        }
    }
}